home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 August: Tool Chest / Dev.CD Aug 98 TC.toast / Sample Code / Networking / JSaver / Source / StubMod.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-06-05  |  3.4 KB  |  133 lines  |  [TEXT/MPCC]

  1. /*
  2.     StubMod.c
  3.     This file creates the 68k 'ADgm' resource to call your PPC module.
  4.     Its designed to be compiled as a code resource and then included in your PPC shared libary project.
  5.  
  6.     Created by Steve Zellers
  7.     6/2/95    aea (Andrew Armstrong) Modifed for CodeWarrior & proper CPU checking.
  8.     05/30/96    smz        rewrote for "fat" CFM modules
  9. */
  10.  
  11. #define GENERATING68K 1
  12. #include <ConditionalMacros.h>
  13. #include <CodeFragments.h>
  14. #include <MixedMode.h>
  15. #include <Types.h>
  16. #include <OSUtils.h>
  17. #include <Resources.h>
  18. #include <Memory.h>
  19. #include <A4Stuff.h>
  20. #include <Quickdraw.h>
  21. #include <LowMem.h>
  22. #include <GestaltEqu.h>
  23.  
  24. #include "GraphicsModule_Types.h"
  25.  
  26. #define kFragmentName    "\pmain"
  27. #define kEntryPointName    "\pmain"
  28.  
  29. typedef pascal OSErr (*ModuleProcPtr)(Handle* storage, RgnHandle rgn, short msg, GMParamBlockPtr params);
  30.  
  31. enum {
  32.     eModuleDispatchSelector = kPascalStackBased
  33.          | RESULT_SIZE(SIZE_CODE(sizeof(OSErr)))
  34.          | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof( Handle*)))
  35.          | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof( RgnHandle)))
  36.          | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(short)))
  37.          | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof( GMParamBlock*)))
  38. };
  39.  
  40. static ConnectionID theConnectionID;
  41. static Ptr theEntryPoint;
  42. static ModuleProcPtr theDescriptor = nil;
  43.  
  44. static OSErr LocateFile(short refNum, FSSpec* location, long* fileLen)
  45. {
  46.     FCBPBRec fcbPB;
  47.     OSErr result;
  48.  
  49.     fcbPB.ioNamePtr = (StringPtr)location->name;
  50.     fcbPB.ioCompletion = nil;
  51.     fcbPB.ioFCBIndx = 0;
  52.     fcbPB.ioRefNum = refNum;
  53.     result = PBGetFCBInfo(&fcbPB, false);
  54.     if (result == noErr) {
  55.         location->vRefNum = fcbPB.ioFCBVRefNum;
  56.         location->parID = fcbPB.ioFCBParID;
  57.         *fileLen = fcbPB.ioFCBPLen;
  58.     }
  59.  
  60.     return result;
  61. }
  62.  
  63. static Boolean onPowerPC()
  64. {
  65.     long result;
  66.     return Gestalt(gestaltNativeCPUtype, &result) == noErr && result >= gestaltCPU601;
  67. }
  68.  
  69. static RoutineDescriptor theRTD = BUILD_ROUTINE_DESCRIPTOR(eModuleDispatchSelector, nil);
  70.  
  71. pascal OSErr main(Handle* storage, RgnHandle rgn, short msg, GMParamBlockPtr params)
  72. {
  73.     OSErr err = noErr;
  74.     long cfmPresent;
  75.     long oldA4;
  76.  
  77.     oldA4 = SetCurrentA4();
  78.  
  79.     err = Gestalt(gestaltCFMAttr, &cfmPresent);
  80.     if (err != noErr) {
  81.         Handle errorHandle;
  82.         
  83.         errorHandle = Get1Resource('STR ', 150);
  84.         
  85.         if (!errorHandle)
  86.             BlockMove("\pSorry, this module requires the Code Fragment Manager.", params->errorMessage, 255);
  87.         else {
  88.             HLock(errorHandle);
  89.             BlockMove(*errorHandle, params->errorMessage, 255);
  90.             ReleaseResource(errorHandle);
  91.         }
  92.  
  93.         ExitCodeResource();
  94.         return -1;    
  95.     }
  96.  
  97.     // open the fragment
  98.     if (msg == Initialize || msg >= ButtonMessage) {
  99.         Ptr exportedEntryPoint;
  100.         SymClass theClass;
  101.         FSSpec thisSpec;
  102.         long thisLen;
  103.  
  104.         LocateFile(LMGetCurMap(), &thisSpec, &thisLen);
  105.         err = GetDiskFragment(&thisSpec, 0, kWholeFork, kFragmentName, kLoadNewCopy, &theConnectionID, (Ptr*) &exportedEntryPoint, params->errorMessage);
  106.  
  107.         if (err == noErr)
  108.             err = FindSymbol(theConnectionID, kEntryPointName, &theEntryPoint, &theClass);
  109.     
  110.         if (err == noErr) {
  111.             theRTD.routineRecords[0].procDescriptor = (ProcPtr) theEntryPoint;
  112.             if (onPowerPC()) {
  113.                 theRTD.routineRecords[0].ISA = kPowerPCISA | kPowerPCRTA;
  114.             } else {
  115.                 theRTD.routineRecords[0].ISA = kM68kISA | kCFM68kRTA;
  116.             }
  117.             theDescriptor = (ModuleProcPtr) &theRTD;
  118.         }
  119.     }
  120.     
  121.     if (theDescriptor && (err == noErr)) {
  122.         err = (*theDescriptor)(storage, rgn, msg, params);
  123.     }
  124.  
  125.     if (msg == Close || err != noErr || msg >= ButtonMessage) {
  126.         CloseConnection(&theConnectionID);
  127.  
  128.     }
  129.  
  130.     ExitCodeResource();
  131.     return err;
  132. }
  133.